/*
  ID: nemokin1
  PROG: cowtour
  LANG: C++
*/
#include <vector>
#include <list>
#include <assert.h>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <fstream>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>
 
using namespace std;
 
#define REP(i,n) for(int i=0; i<(n); ++i)
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define FORD(i,a,b) for(int i=(a);i>=b;--i)
#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define ALL(c) (c).begin(),(c).end()
 
#define debug(x) cerr<< #x << " = " << (x) << "\n";
#define debugv(v) cerr << #v << " = "; FOREACH(it,v) cerr << *it <<","; cerr << "\n";
#define SIZE(a)  (int(a.size()))
 
template<typename T> inline void checkMax(T& a, T b) {if (b>a) a=b;}
template<typename T> inline void checkMin(T& a, T b) {if (b<a) a=b;}
 
typedef long long LL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int,int>  ii;
typedef long double ld;
const double INF = 1000000000.0;

vector<ii> vp;
vector<string> vs;
double dis(int i, int j)
{
    double x = vp[i].first-vp[j].first;
    double y = vp[i].second-vp[j].second;
    return sqrt(x*x+y*y);
}

/*
8
10 10
15 10
20 10
15 15
20 15
30 15
25 10
30 10
01000000
10111000
01001000
01001000
01110000
00000010
00000101
00000010
*/
double dist[200][200];

int main() {
    freopen("cowtour.in","r",stdin);freopen("cowtour.out","w",stdout);
    int N;
    cin >> N;
    for(int i = 0; i < N; i++){
	int m,n;
	cin >> m >> n;
	vp.push_back(ii(m,n));
    }
    for(int i = 0; i < N; i++){
	string s;
	cin >> s;
	vs.push_back(s);
    }

    double ret = INF;
    
    for(int i = 0; i < N; i++)
	for(int j = 0; j < N; j++)
	    if(i == j) dist[i][j] = 0;
	    else if(vs[i][j]=='1')
		dist[i][j] =  dis(i,j);
	    else dist[i][j] = INF;
    
    
    for(int k = 0; k < N; k++)
	for(int i = 0; i < N; i++)
	    for(int j = 0; j < N; j++)
		if(dist[i][k]+dist[k][j] < dist[i][j])
		    dist[i][j] = dist[i][k]+dist[k][j];
    REP(i,N) REP(j,N) if(dist[i][j]==INF) dist[i][j]=-1.0;
    // for(int i = 0; i < N; i++){
    // 	for(int j = 0; j < N; j++)
    // 	    cout<<dist[i][j]<<" ";
    // 	cout<< endl;
    // }
    for(int i = 0; i < N; i++){
	for(int j = i+1; j < N; j++){
	    if(dist[i][j] == -1.0){
		checkMin(ret,dis(i,j)+
			 *max_element(dist[i],dist[i]+N)+*max_element(dist[j],dist[j]+N));
	    }
	}
    }
    double cc = 0.0;
    
    REP(i,N)REP(j,N) if(dist[i][j] != -1.0) checkMax(cc,dist[i][j]);
    checkMax(ret,cc);
    
    printf("%.6f\n",ret);
    
}

    

